package com.sz.app.edi.base.service.impl;

import com.sz.app.edi.constants.EdiErrorCodes;
import com.sz.app.edi.base.entity.SynCompanyAccount;
import com.sz.app.edi.base.service.SynCompanyAccountService;
import com.sz.app.edi.base.dto.AccessToken;
import com.sz.biz.common.customer.entity.CusUser;
import com.sz.biz.common.customer.service.CustomerUserService;
import com.sz.biz.common.sup.service.impl.SupplierUserConfigServiceImpl;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.exception.BizException;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.StringUtils;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Function: SynCompanyServcieImpl. <br>
 * Date: 2017年07月04日 16:35 <br>
 *
 * @author wentao.chang
 */
@Service
public class SynCompanyAccountServcieImpl extends AbstractService implements SynCompanyAccountService {


    @Autowired
    private CustomerUserService customerUserService;

    /**
     * 注册供应商客户系统的账户
     *
     * @param type         1供应商  2客户
     * @param bizId        供应商或者客户的ID
     * @param bizAccountId 供应商或者客户的账户ID
     */
    @Override
    public SynCompanyAccount registryEdiAccount(int type, int bizId, int bizAccountId) {
        CusUser cusUser = customerUserService.findShortById(bizAccountId);
        if (cusUser.getRefCustomerId() != bizId) {
            throw Exceptions.bizException(EdiErrorCodes.ERROR_EDI_ACCOUNT_NOTMATCH);
        }
        SynCompanyAccount synCompany = new SynCompanyAccount();
        synCompany.setType(type);
        synCompany.setBizId(bizId);
        synCompany.setBizAccountId(bizAccountId);
        synCompany.setIsDeleted(false);
        synCompany.setClientId(UUID.randomUUID().toString().toLowerCase());
        String apikey = UUID.randomUUID().toString();
        synCompany.setApiKey(apikey.toLowerCase().replaceAll("-", ""));
        String securityKey = UUID.randomUUID().toString() + "-" + UUID.randomUUID().toString();
        synCompany.setSecurityKey(securityKey.toLowerCase().replaceAll("-", ""));

        dao.save("edi.SynCompanyAccountMapper.insert", synCompany);
        return synCompany;
    }

    /**
     * 注销供应商客户系统的账户
     *
     * @param type         1供应商  2客户
     * @param bizId        供应商或者客户的ID
     * @param bizAccountId 供应商或者客户的账号ID
     */
    @Override
    public void deleteEdiAccount(int type, int bizId, int bizAccountId) {
        CusUser cusUser = customerUserService.findShortById(bizAccountId);
        if (cusUser.getRefCustomerId() != bizId) {
            throw Exceptions.bizException(EdiErrorCodes.ERROR_EDI_ACCOUNT_NOTMATCH);
        }
        Map<String, Object> map = new HashMap<>(16);
        map.put("type", type);
        map.put("bizId", bizId);
        map.put("bizAccountId", bizAccountId);
        dao.update("edi.SynCompanyAccountMapper.deleteByBizAccountIdAndType", map);
    }

    /**
     * 验证apiKey securityKey 是否匹配
     *
     * @param apiKey      apiKey
     * @param securityKey securityKey
     */
    @Override
    public SynCompanyAccount validAccount(String apiKey, String securityKey) {
        SynCompanyAccount synCompany = (SynCompanyAccount) dao.findForObject("edi.SynCompanyAccountMapper.findByApiKey", apiKey);
        if (synCompany == null || !securityKey.equals(synCompany.getSecurityKey())) {
            throw Exceptions.bizException(EdiErrorCodes.ERROR_EDI_APIKEY_SECURITYKEY_NOTMATCH);
        }
        if (synCompany.getIsDeleted()) {
            throw Exceptions.bizException(EdiErrorCodes.ERROR_EDI_APIKEY_SECURITYKEY_NOTMATCH);
        }
        return synCompany;
    }

    /**
     * 验证token
     *
     * @param token token
     */
    @Override
    public SynCompanyAccount validToken(String token) {
        SynCompanyAccount synCompany = (SynCompanyAccount) dao.findForObject("edi.SynCompanyAccountMapper.findByToken", token);
        if (synCompany == null || synCompany.getIsDeleted()) {
            throw Exceptions.bizException(EdiErrorCodes.ERROR_EDI_TOKEN_NOT_VALID);
        }
        if (synCompany.getExpireTime().compareTo(new Date()) < 0) {
            throw Exceptions.bizException(EdiErrorCodes.ERROR_EDI_TOKEN_EXPIRED);
        }
        return synCompany;
    }

    @Override
    public void reRegistryEdiAccount(SynCompanyAccount sca) {
        String securityKey = UUID.randomUUID().toString() + "-" + UUID.randomUUID().toString();
        sca.setSecurityKey(securityKey.toLowerCase().replaceAll("-", ""));

        sca.setToken(null);
        sca.setExpire(null);
        sca.setExpireTime(null);
        dao.update("edi.SynCompanyAccountMapper.updateSecurityKey", sca);

    }

    /**
     * 更新token以及token的有效期
     *
     * @param apiKey      apiKey
     * @param securityKey securityKey
     */
    @Override
    public AccessToken generateToken(String apiKey, String securityKey) {
        //token 有效期1个小时
        int one_hour = 60 * 60 * 1000;
        //先校验
        SynCompanyAccount synCompany = validAccount(apiKey, securityKey);
        if (!customerUserService.isUserValid(synCompany.getBizAccountId())) {
            throw  Exceptions.bizException(EdiErrorCodes.ERROR_EDI_USER_VALID);
        }
        String token = UUID.randomUUID().toString();
        synCompany.setToken(token.toLowerCase().replaceAll("-", ""));

        synCompany.setExpire(one_hour);
        Date expireTimeStamp = new Date(System.currentTimeMillis() + one_hour);
        synCompany.setExpireTime(expireTimeStamp);
        dao.update("edi.SynCompanyAccountMapper.updateToken", synCompany);

        AccessToken accessToken = new AccessToken();
        accessToken.setExpireTimeStamp(expireTimeStamp.getTime());
        accessToken.setClientId(synCompany.getClientId());
        accessToken.setToken(synCompany.getToken());

        return accessToken;
    }

    /**
     * 更新其他信息，包含推消息的信息
     *
     * @param id id
     */
    @Override
    public void updateDetailInfo(int id) {

    }

    @Override
    public SynCompanyAccount findByBizAccountIdAndType(Integer type, Integer bizId, Integer bizAccountId) {
        SynCompanyAccount synCompany = null;
        if (bizId != null && type != null) {
            ParamData pd = new ParamData();
            pd.put("bizId", bizId);
            pd.put("type", type);
            pd.put("bizAccountId", bizAccountId);
            synCompany = (SynCompanyAccount) dao.findForObject("edi.SynCompanyAccountMapper.findByBizAccountIdAndType", pd);
        }
        return synCompany;
    }

    @Override
    public List<SynCompanyAccount> findByBizIdListAndType(List<Integer> bizIdList, Integer type) {
        List<SynCompanyAccount> synCompanys = new ArrayList<>();
        if (!CollectionUtils.isEmpty(bizIdList) && type != null && type > 0) {
            ParamData pd = new ParamData();
            pd.put("bizIds", bizIdList);
            pd.put("type", type);
            synCompanys = dao.findForList("edi.SynCompanyAccountMapper.findByBizIdListAndType", pd, SynCompanyAccount.class);
        }
        return synCompanys;

    }

    @Override
    public SynCompanyAccount findByToken(String token) {
        SynCompanyAccount synCompany = null;
        if (!StringUtils.isEmpty(token)) {
            ParamData pd = new ParamData();
            pd.put("token", token);
            synCompany = (SynCompanyAccount) dao.findForObject("edi.SynCompanyAccountMapper.findByToken", pd);
        }
        return synCompany;
    }

    @Override
    public SynCompanyAccount findByClientId(String clientId) {
        SynCompanyAccount synCompany = null;
        if (!StringUtils.isEmpty(clientId)) {
            synCompany = (SynCompanyAccount) dao.findForObject("edi.SynCompanyAccountMapper.findByClientId", clientId);
        }
        return synCompany;
    }
}
